package infrastructure

import (
	"context"
	"time"

	"gopkg.openfuyao.cn/bkeadm/pkg/executor/containerd"
	"gopkg.openfuyao.cn/bkeadm/pkg/executor/docker"
	"gopkg.openfuyao.cn/bkeadm/pkg/global"
	cond "gopkg.openfuyao.cn/bkeadm/pkg/infrastructure/containerd"
	"gopkg.openfuyao.cn/bkeadm/pkg/infrastructure/dockerd"
	"gopkg.openfuyao.cn/bkeadm/pkg/infrastructure/k3s"
	"gopkg.openfuyao.cn/bkeadm/utils"
	"gopkg.openfuyao.cn/bkeadm/utils/log"
)

// IsDocker 判断是否安装docker
func IsDocker() bool {
	if global.Docker == nil {
		global.Docker, _ = docker.NewDockerClient()
	}
	if global.Docker != nil {
		// 变更为timout请求
		ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
		defer cancel()
		_, err := global.Docker.GetClient().Ping(ctx)
		if err == nil {
			log.Info("The docker client is ready.")
			return true
		}
	}
	return false
}

// IsContainerd 判断是否安装containerd
func IsContainerd() bool {
	if global.Containerd == nil {
		global.Containerd, _ = containerd.NewContainedClient()
	}
	if global.Containerd != nil {
		ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
		defer cancel()
		flag, err := global.Containerd.GetClient().IsServing(ctx)
		if flag && err == nil {
			if !utils.Exists(utils.NerdCtl) {
				log.Debug("The /usr/bin/nerdctl tool was not found.")
				return false
			}
			return true
		}
	}
	return false
}

// RuntimeInstall
// 优先安装containerd
// 当没有containerd包时，安装docker
func RuntimeInstall(runtime, runtimeStorage, domain, containerdFile, cniPluginFile, dockerdFile, hostIp, caFile string) error {
	if IsDocker() || IsContainerd() {
		return nil
	}
	if runtime == "docker" {
		return dockerd.EnsureDockerServer(domain, runtimeStorage, dockerdFile, hostIp)
	}

	err := cond.Install(domain, runtimeStorage, containerdFile, caFile)
	if err != nil {
		return err
	}

	if len(cniPluginFile) > 0 {
		err = cond.CniPluginInstall(cniPluginFile)
		if err != nil {
			return err
		}
	}
	return nil
}

// StartLocalKubernetes
// kind docker 集群废弃的
// k3s containerd 当前支持
func StartLocalKubernetes(otherRepo, otherRepoIp, hostIP, imageRepo, imageRepoPort, kubernetesPort string) error {
	if IsDocker() {
		err := k3s.StartK3sWithDocker(otherRepo, otherRepoIp, hostIP, imageRepo, imageRepoPort, kubernetesPort)
		if err != nil {
			return err
		}
	}
	if IsContainerd() {
		err := k3s.EnsureDirExists(utils.DefaultExtendManifestsDir)
		if err != nil {
			return err
		}
		err = k3s.StartK3sWithContainerd(otherRepo, otherRepoIp, hostIP, imageRepo, imageRepoPort, kubernetesPort)
		if err != nil {
			return err
		}
		err = k3s.ModK3sCorednsImage(otherRepo, imageRepo)
		if err != nil {
			return err
		}
	}
	return nil
}
